package com.jd.oneday.month3;

/**
 * 创建一个环形的单向链表
 *
 * @author Administrator
 * first 创建一个first节点，当前没有编号
 */

public class Day15_CircularSingleLinkedList {

    private Day15_Boy first = new Day15_Boy(0);


    /**
     * @param starNo   编号(从那开始)
     * @param countNum 数几下
     * @param nums     最初有多少小孩
     */
    public void countBoy(int starNo, int countNum, int nums) {
        //先对数据校验
        if (first == null || starNo < 1 || starNo > nums) {
            System.out.println("参数输入有误，请重新输入");
            return;
        }

        //创建辅助指针
        Day15_Boy helper = first;
        //让helper指向链表的最后一个节点
        while (true) {
            //判断helper是否指向了最后一个节点
            if (helper.getNext() == first) {
                break;
            }
            //helper后移
            helper = helper.getNext();
        }

        //小孩报数，先让fiesta和helper移动K-1次
        for (int j = 0; j < starNo - 1; j++) {
            first = first.getNext();
            helper = helper.getNext();
        }

        //当小孩报数时，让fiesta和helper同时移动M-1次，然后出圈
        while (true) {
            //判断圈中是否只剩一个节点
            if (helper == first) {
                break;
            }
            //让first和helper指针同时移动countNum - 1
            for (int j = 0; j < countNum - 1; j++) {
                first = first.getNext();
                helper = helper.getNext();
            }
            //这时first指向的节点就是要出圈的小孩节点
            System.out.println(first.getNo() + "小孩出圈了");
            //这时将first指向的小孩节点出圈
            first = first.getNext();
            helper.setNext(first);
        }
        System.out.println("最后留着圈中的小孩是" + first.getNo());
    }


    /**
     * 添加小孩节点，构建成一个环形链表
     *
     * @param nums 整个环形链表有几个小孩
     */
    public void addBoy(int nums) {
        //nums做一个数据校验
        if (nums < 1) {
            System.out.println("nums值不正确");
            return;
        }

        //辅助指针，帮助构建环形链表
        Day15_Boy curBoy = null;
        //使用for循环来创建环形链表
        for (int i = 1; i <= nums; i++) {
            //根据编号创建小孩节点
            Day15_Boy boy = new Day15_Boy(i);

            //如果是第一个小孩
            if (i == 1) {
                first = boy;
                //构成环状
                first.setNext(first);
                //让curBoy指向第一个小孩
                curBoy = first;
            } else {
                //将新节点添加在链表后面
                curBoy.setNext(boy);
                //将最后一个节点指向首节点
                boy.setNext(first);
                //辅助指针后移
                curBoy = boy;
            }
        }
    }

    /**
     * 遍历环形链表
     */
    public void showBoy() {
        //链表是否为空
        if (first == null) {
            System.out.println("链表为空，没有小孩");
            return;
        }
        //因为first不能动，所以需要一个辅助指针完成遍历
        Day15_Boy curBoy = first;
        while (true) {
            System.out.print("小孩的编号" + curBoy.getNo());
            System.out.println();
            //说明遍历完毕
            if (curBoy.getNext() == first) {
                break;
            }
            ;
            //后移
            curBoy = curBoy.getNext();
        }
    }
}